//------------------------------------------------------------------------------
//  <copyright file="IFRIRemote.h" company="Microsoft Corporation">
// The MIT License (MIT)
// 
// Copyright (c) 2014, Microsoft Corporation
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//  </copyright>
//------------------------------------------------------------------------------	

#pragma once

/// <remarks>
/// The FRI binaries included in external have been linked against this interface.
/// The source for building these binaries is not included in the source tree,
/// only the libraries and the header files are included in main\external.
/// This interface cannot be changed without updating these headers and binaries.
/// The only change that can be made without doing this is to include additional 
/// members/methods that the KUKA friremote class already supports.
///
/// Style violations are due to use of conventions present in KUKA code.
/// </remarks>

#define DEFAULT_FRI_SERVER_PORT 49938

#include "friComm.h"

class IFRIRemote
{
public:
	IFRIRemote(int port = DEFAULT_FRI_SERVER_PORT, char * hintToRemoteHost = 0) { };
	~IFRIRemote() { };

	/// <summary> Excange data with FRI client.  Blocks on next packet from FRI client. </summary>
	/// <returns> 0 on success.  -1 on failure. </returns>
	virtual int doDataExchange() = 0;

	/// <summary> Receive data from FRI client.  Blocks on next packet from FRI client. </summary>
	/// <returns> 0 on success.  -1 on failure. </returns>
	virtual int doReceiveData() = 0;

	/// <summary> Send data to the FRI client.  </summary>
	/// <returns> 0 on success.  -1 on failure. </returns>
	virtual int doSendData() = 0;

	/// <summary> Execute a position control command. </summary>
	/// <param name="newJntPosition"> Target joint position. </param>
	/// <param name="flagDataExchange"> 
	/// Indicates whether or not to automatically exchange data with the FRI client before returning.
	/// </param>
	/// <returns> 0 on success.  -1 on failure. </returns>
	virtual int doPositionControl(float newJntPosition[LBR_MNJ], bool flagDataExchange=true) = 0;

	/// <summary> Executes a joint impdance control command. </summary>
	/// <param name="newJntPosition"> Joint positions.  Null value ignored. </param>
	/// <param name="newJntStiff"> Joint stiffness.  Null value ignored. </param>
	/// <param name="newJntDamp"> Joint damping.  Null value ignored.   </param>
	/// <param name="newJntAddTorque"> Additional torque.  Null values ignored. </param>
	/// <param name="flagDataExchange"> 
	/// Indicates whether or not to automatically exchange data with the FRI client before returning.
	/// </param>
	/// <returns> 0 on success.  -1 on failure. </returns>
	virtual int doJntImpedanceControl(
		const float newJntPosition[LBR_MNJ], 
		const float newJntStiff[LBR_MNJ] = NULL,
		const float newJntDamp[LBR_MNJ]=NULL,
		const float newJntAddTorque[LBR_MNJ]=NULL,
		bool flagDataExchange=true) = 0;

	/// <summary> Execute a cartesion impedance command </summary>
	/// <param name="newCartStiff"> Cartesian stiffness. Null value ignored. </param>
	/// <param name="newCartDam"> Cartesian damping.  Null value ignored. </param>
	/// <param name="newAddTcpFT> Additional force and torque on the TCP. </param>
	/// <param name="newJntNullspace"> Joint nullspace. </param>
	/// <param name="flagDataExchange"> 
	/// Indicates whether or not to automatically exchange data with the FRI client before returning.
	/// </param>
	/// <returns> 0 on success.  -1 on failure. </returns>
	virtual int doCartesianImpedanceControl(const float newCartPosition[FRI_CART_FRM_DIM], 
		const float newCartStiff[FRI_CART_VEC]=NULL, 
		const float newCartDamp[FRI_CART_VEC]=NULL, 
		const float newAddTcpFT[FRI_CART_VEC]=NULL,
		const float newJntNullspace[LBR_MNJ]=NULL,
		bool flagDataExchange=true) = 0;

	/// <summary> Get the state of the FRI connection. </summary>
	/// <returns> State of the FRI connection. </returns>
	virtual FRI_STATE getState() = 0;

	/// <summary> Get the quality of the FRI connection. </summary>
	/// <returns> Quality of the FRI connection. </returns>
	virtual FRI_QUALITY getQuality() = 0;
	
	/// <summary> Get the current measured joint position. </summary>
	/// <returns> The current measured joint position. </returns>
	virtual float* getMsrMsrJntPosition() = 0;

	/// <summary> Get the current measured commanded cartesian position. </summary>
	/// <returns> the current measured commanded cartesian position. </returns>
	virtual float* getMsrCmdCartPosition() = 0;

	/// <summary> Get the current measured cartesian position. </summary>
	/// <returns> The current measured cartesian position. </summary>
	virtual float* getMsrCartPosition() = 0;

	/// <summary> Get the data stored in the msr buffer. </summary>
	/// <returns> The data stored in the msr buffer. </returns>
	virtual tFriMsrData & getMsrBuf() = 0;

	/// <summary> Get real value from KRL.  Corresponds to KRL variable $FRI_TO_REA </summary>
	/// <param name=index> Index of the real value to get </param>
	/// <returns> A float. </returns>
	virtual float getFrmKRLReal(int index) = 0;

	/// <summary> Set a real value to KRL. Corresponds to KRL variable $FRI_FRM_REA </summary>
	/// <param name=index> Index of the real value to set. </param>
	/// <param name=val> Value to set. </param>
	virtual void  setToKRLReal(int index, float val) = 0;

	/// <summary> Get integer value from KRL.  Corresponds to KRL variable $FRI_TO_INT </summary>
	/// <param name=index> Index of the integer value to get </param>
	/// <returns> An int. </returns>
	virtual int   getFrmKRLInt(int index) = 0;

	/// <summary> Set a integer value to KRL. Corresponds to KRL variable $FRI_FRM_INT </summary>
	/// <param name=index> Index of the integer value to set. </param>
	/// <param name=val> Value to set. </param>
	virtual void  setToKRLInt(int index, int val) = 0;

	/// <summary> Get bool value from KRL.  Corresponds to KRL variable $FRI_TO_BOOL </summary>
	/// <param name=index> Index of the bool value to get </param>
	/// <returns> A bool. </returns>
	virtual bool  getFrmKRLBool(int index) = 0;

	/// <summary> Get all bool values from KRL.  Corresponds to KRL variable $FRI_TO_BOOL </summary>
	/// <returns> A 16-bit value corresponding to all bool values in $FRI_TO_BOOL bool. </returns>
	virtual fri_uint16_t getFrmKRLBool() = 0;

	/// <summary> Set a bool value to KRL. Corresponds to KRL variable $FRI_FRM_BOOL </summary>
	/// <param name=index> Index of the bool value to set. </param>
	/// <param name=val> Value to set. </param>
	virtual void  setToKRLBool(int index, bool val) = 0;

	/// <summary> Set all bool values to KRL. Corresponds to KRL variable $FRI_FRM_BOOL </summary>
	/// <param name=val> A 16-bit value corresponding to all bool values to set to $FRI_FRM_BOOL bool. </param>
	virtual void setToKRLBool(fri_uint16_t val) = 0;
};
